/*
 * RSA.h
 *
 *  Created on: Nov 12, 2011
 *      Author: kimi
 */

#ifndef RSA_H_
#define RSA_H_

#include "../Configuration/Properties.h"
#include <math.h>
#include <time.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <sstream>

using namespace std;

class RSA {
public:
	RSA(unsigned long _key_length);
	virtual ~RSA();

	void generateNAndPhi(unsigned long *n, unsigned long *phi);
	void generatePrivateAndPublicKey(unsigned long n, unsigned long phi, unsigned long *pk, unsigned long *pu);

	bool createPrivateKeyFile(string file, unsigned long d, unsigned long n);
	bool createPublicKeyFile(string file, unsigned long e, unsigned long n);

	unsigned long encrypt(unsigned long e, unsigned long n, unsigned long msg);
	unsigned long decrypt(unsigned long d, unsigned long n, unsigned long msg);

	string encrypt(unsigned long e, unsigned long n, string msg);
	string decrypt(unsigned long d, unsigned long n, string msg);

	bool encrypt(unsigned long e, unsigned long n, string sourceFile, string destFile);
	bool decrypt(unsigned long d, unsigned long n, string sourceFile, string destFile);

	bool encryptBinaryFile(unsigned long e, unsigned long n, string sourceFile, string destFile);
	bool decryptBinaryFile(unsigned long d, unsigned long n, string sourceFile, string destFile);

	bool isPrime(unsigned long num);

private:
	unsigned long key_length;

	void generatePAndQ(unsigned long *p,unsigned long* q);


	unsigned long* euclides(unsigned long a, unsigned long b);
	unsigned long long mod_inv(unsigned long long a, unsigned long long n, unsigned long long* inv);
	unsigned long long ext_mcd (unsigned long long a, unsigned long long b, unsigned long long r[2]);
	unsigned long long mcd (unsigned long long a, unsigned long long b);
	unsigned long long mod_exp (unsigned long long b, unsigned long long e, unsigned long long m);
	unsigned long gcd(unsigned long a, unsigned long b);
};

#endif
